/**
 * 预加载指令 - 用于提前加载可能需要的资源（图片、字体、CSS、JS等）
 * 
 * 使用方法:
 * 1. 图片预加载: v-prefetch="{ type: 'image', src: 'https://example.com/image.jpg' }"
 * 2. 资源预加载: v-prefetch="{ type: 'resource', src: 'https://example.com/style.css', as: 'style' }"
 * 3. 路由预加载: v-prefetch="{ type: 'route', path: '/user/profile' }"
 */

import type { DirectiveBinding } from 'vue';

interface PrefetchOptions {
  type: 'image' | 'resource' | 'route';
  src?: string;
  as?: string;
  path?: string;
}

const prefetchDirective = {
  mounted(el: HTMLElement, binding: DirectiveBinding<PrefetchOptions>) {
    const options = binding.value;
    
    if (!options || !options.type) {
      console.warn('Prefetch directive requires a valid configuration object');
      return;
    }
    
    // 仅在支持Intersection Observer的浏览器中使用
    if (!('IntersectionObserver' in window)) return;
    
    const observer = new IntersectionObserver((entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          // 元素进入视口，开始预加载
          switch (options.type) {
            case 'image':
              if (options.src) {
                const img = new Image();
                img.src = options.src;
              }
              break;
              
            case 'resource':
              if (options.src) {
                const link = document.createElement('link');
                link.rel = 'prefetch';
                if (options.as) link.setAttribute('as', options.as);
                link.href = options.src;
                document.head.appendChild(link);
              }
              break;
              
            case 'route':
              // 路由预加载暂不实现，避免循环依赖问题
              if (options.path && options.src) {
                // 直接预加载资源
                const link = document.createElement('link');
                link.rel = 'prefetch';
                link.href = options.src;
                document.head.appendChild(link);
              }
              break;
          }
          
          // 预加载后取消观察
          observer.unobserve(el);
        }
      });
    }, {
      // 设置阈值，当元素有50%在视口中时触发
      threshold: 0.5,
      // 设置根边距，在元素进入视口前100px就开始预加载
      rootMargin: '100px'
    });
    
    observer.observe(el);
  }
};

export default prefetchDirective; 